import React, {useRef} from 'react';
import {useDrag, useDrop, XYCoord} from "react-dnd";
import BaseChart from '@/chart/baseChart';
import MapChart from '@/chart/mapChart';
import {useJsonStore} from "../provider";
import {BigScreenCanvas} from "@/BigScreenCanvas";
import {ColFlex, FlexItem, RowFlex} from "@/LayoutComponent";
export default function Element(props){
    const {json,isLayoutChildren} = props;
    const {pageJson,setPageJson,setCurrentComponent} = useJsonStore();
    let elements = null;
    const dragRef = useRef();
    const [{ isDragging }, drag,dargpreview] = useDrag({
        item: { type: 'box',dragItem:{...json} },
        end: (item, monitor) => {
            const dropResult = monitor.getDropResult();
            if (item && dropResult) {
                // alert(`You dropped into ${dropResult.name}!`);
                //checkIsComponentExist(json,item['dragItem']['']);
                //setPageJson();
                // 如果是end在这个位置意味着在该组件中拖拽

            }
        },
        collect: (monitor) => ({
            isDragging: monitor.isDragging(),
        }),
    });

    // 移动节点
    const moveComponent = (id:string,left:number,top:number,json:{})=>{
        const jsonData = {...json};
        if(id === jsonData['id']){
            return {...jsonData,
                addition:{
                    ...jsonData['addition'],
                    position:{
                        ...jsonData['addition']['position'],
                        left:left,
                        top:top
                    }
                }
            }
        }else{
            if(jsonData['children'] && jsonData['children']['length'] > 0){
                const children = jsonData['children'];
                const newChildren = children.map((value)=>{
                    return moveComponent(id,left,top,value);
                });
                return {...jsonData,
                    children:newChildren
                }
            }else{
                return jsonData;
            }
        }
    };

    // 添加新节点
    const addNewComponent = (id:string,dragItem:{},json:{}) =>{
        const jsonData = {...json};
        if(id === jsonData['id']){
            return {...jsonData,
                children:[
                    ...jsonData['children'],
                    {
                        ...dragItem,
                    }
                ]
            }
        }
        else{
            if(jsonData['children'] && jsonData['children']['length'] > 0){
                const children = jsonData['children'];
                const newChildren = children.map((value)=>{
                    return addNewComponent(id,dragItem,value);
                });
                return {...jsonData,
                    children:newChildren
                }
            }else{
                return jsonData;
            }
        }
    };

    // 删除节点
    const deleteComponent = (id:string,json:{}) =>{
        const children = json['children'];
        if(children && children['length'] > 0){
            const newChildren = children.filter((value)=>{
               return value['id'] != id;
            });
            if(newChildren['length'] == children['length']){
                const newChildren = children.map((value)=>{
                    if(value['children'] && value['children']['length'] > 0){
                        return deleteComponent(id,value);
                    }else{
                        return value;
                    }
                });
                return {
                    ...json,
                    children:newChildren
                }
            }
            return {
                ...json,
                children:newChildren
            }

        }
        return json;
    };

    // 改变节点内容
    const changeComponent = (id:string,json:{},alljson:{})=>{
        const jsonData = {...alljson};
        if(id === jsonData['id']){
            return {...json}
        }
        else{
            if(jsonData['children'] && jsonData['children']['length'] > 0){
                const children = jsonData['children'];
                const newChildren = children.map((value)=>{
                    return changeComponent(id,json,value);
                });
                return {...jsonData,
                    children:newChildren
                }
            }else{
                return jsonData;
            }
        }
    };

    // 切换父子，删除原来的，换到新的父节点上去
    const checkIsComponentExist = (componentList,id,oldParentId,realParentId)=>{
        let checkResult = undefined;
        componentList.forEach((value)=>{
            const tempId = value['id'];
            if(tempId == id && oldParentId == realParentId || id == realParentId){
                checkResult = {
                    type:'notNeedChange',
                    item:null
                };
            }else if(tempId === id && oldParentId != realParentId){
                // 需要删除原节点
                checkResult = {
                    type:'needChange',
                    item:value
                };
            }else if(!checkResult){
                const tempChildren = value['children'];
                if(tempChildren && tempChildren['length'] > 0){
                    checkResult = checkIsComponentExist(tempChildren,id,value['id'],realParentId);
                }
            }
        });

        return checkResult;
    };

    const [{ canDrop,isOver }, drop] = useDrop({
        accept: 'box',
        drop(item, monitor) {
            const didDrop = monitor.didDrop();
            const perantType = json['type']['name'];
            if (didDrop || perantType == 'normalcharts' || perantType == 'mapcharts') {
                return;
            }
            let delta = null;
            let itemLeft = 0;
            let itemTop = 0;
            let newDragItem = {};
            const id = item['dragItem']['id'];
            const oldId = pageJson['id'];
            const realId = json['id'];
            if(id == 'mainPage'){
                return;
            }
            const dragItem = item['dragItem'];
            let isExist = undefined;
            if(pageJson['children'] && pageJson['children']['length'] > 0){
                const tempChildren = pageJson['children'];
                isExist = checkIsComponentExist(tempChildren,id,oldId,realId);
            }
            if(!isExist) {
                delta = monitor.getClientOffset() as XYCoord;
                const leftdom = document.getElementsByClassName('dlc-mp-left');
                const parentdom = document.getElementById(realId);
                const leftWidth = leftdom[0].clientWidth;
                delta = {
                    x:delta.x - leftWidth - parentdom.offsetLeft,
                    y:delta.y - parentdom.offsetTop - 116
                };
                const left = Math.round(itemLeft + delta.x);
                const top = Math.round(itemTop + delta.y);
                newDragItem = {...dragItem,addition:{
                        ...dragItem['addition'],
                        position:{
                            ...dragItem['addition']['position'],
                            left:left,
                            top:top
                        }
                    }};
                const newJson = addNewComponent(json['id'],newDragItem,json);
                const resultJson = changeComponent(json['id'],newJson,pageJson);
                setPageJson(resultJson);
            }else if(isExist['type'] == "needChange"){
                delta = monitor.getClientOffset() as XYCoord;
                const leftdom = document.getElementsByClassName('dlc-mp-left');
                const parentdom = document.getElementById(realId);
                const leftWidth = leftdom[0].offsetWidth;
                delta = {
                    x:delta.x - leftWidth - parentdom.offsetLeft,
                    y:delta.y - parentdom.offsetTop - 116
                };
                const left = Math.round(itemLeft + delta.x);
                const top = Math.round(itemTop + delta.y);
                newDragItem = {...dragItem,position:{
                        ...dragItem['addition']['position'],
                        left:0,
                        top:0
                    }};
                const deletedAllJson = deleteComponent(id,pageJson);
                const deleteNowJson = deleteComponent(id,json);
                const newJson = addNewComponent(json['id'],newDragItem,deleteNowJson);
                const resultJson = changeComponent(json['id'],newJson,deletedAllJson);
                setPageJson(resultJson);
            } else{
                // 单纯移动节点
                itemLeft = dragItem['addition']['position']['left'];
                itemTop = dragItem['addition']['position']['top'];
                delta = monitor.getDifferenceFromInitialOffset() as XYCoord;
                const left = Math.round(itemLeft + delta.x);
                const top = Math.round(itemTop + delta.y);
                newDragItem = {...dragItem,position:{
                        ...dragItem['addition']['position'],
                        left:left,
                        top:top
                    }};
                const newJson = moveComponent(id,left,top,pageJson);
                setPageJson(newJson);
            }
            setCurrentComponent(newDragItem);
            return undefined
        },
        hover(item,monitor){
            const didHover = monitor.isOver({ shallow: true });
            // 最小hover进入
            if(didHover){

            }
        },
        collect: monitor => ({
            isOver: monitor.isOver({ shallow: true }),
            canDrop: monitor.canDrop()
        }),
    });
    dargpreview(drop(dragRef));

    if(json){
        const type = json['type']['name'];
        const style = json['props']['style'];
        const id = json['id'];
        // 默认布局是纵向的
        if(type=='bigscreencanvas'){
            if(json['children'] && json['children']['length'] > 0){
                elements = <div onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} id={id} ref={dragRef}>
                    <div ref={drag}>
                        <BigScreenCanvas layout={json['addition']['layout']} {...json['props']}>
                        {json['children'].map((value)=>{
                            return <FlexItem overflow={'hidden'} style={{...value['props']['style']}} flexBasic={value['props']['style']['height']}>
                                        <Element isLayoutChildren={true} key={value['id']} json={value}/>
                                </FlexItem>
                        })}
                        </BigScreenCanvas>
                    </div>
                </div>;
            }else{
                elements = <div onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} id={id} ref={dragRef}>
                    <div ref={drag}>
                        <BigScreenCanvas layout={json['addition']['layout']} {...json['props']}>
                        </BigScreenCanvas>
                    </div>
                </div>;
            }
        }
        else if(type == 'rowlayout'){
            let style = json['props']['style'];
            const position = json['addition']['position'];
            if(isLayoutChildren != undefined && isLayoutChildren){
                // flexitem上已经有了
                style = {};
            }
            if(json['children'] && json['children']['length'] > 0){
                elements = <div onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }
                }} tabIndex={0} id={id} ref={dragRef} style={{...style}}>
                    <div ref={drag}>
                        <RowFlex style={{border:'1px solid',position:'relative',height:'100%',width:'100%'}}>
                            {json['children'].map((value)=>{
                                return <FlexItem overflow={'hidden'} style={{...value['props']['style']}} flexBasic={value['props']['style']['width']}>
                                    <Element isLayoutChildren={true} key={value['id']} json={value}/>
                                </FlexItem>
                            })}
                        </RowFlex>
                    </div>
                </div>
            }
            else{
                elements = <div onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }
                }} tabIndex={0} id={id} ref={dragRef} style={{...style}}>
                    <div ref={drag}>
                        <RowFlex style={{border:'1px solid',position:'relative',height:'100%',width:'100%'}}>
                            {id}
                        </RowFlex>
                    </div>
                </div>
            }
        }
        else if(type == 'collayout'){
            let style = json['props']['style'];
            const position = json['addition']['position'];
            if(isLayoutChildren != undefined && isLayoutChildren){
                // flexitem上已经有了
                style = {};
            }
            if(json['children'] && json['children']['length'] > 0){
                elements = <div onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }else{

                    }
                }} tabIndex={0} id={id} ref={dragRef} style={{...style}}>
                    <div ref={drag}>
                        <ColFlex style={{border:'1px solid'}}>
                        {json['children'].map((value)=>{
                            return <FlexItem overflow={'hidden'} style={{...value['props']['style']}} flexBasic={value['props']['style']['height']}>
                                <Element isLayoutChildren={true} key={value['id']} json={value}/>
                            </FlexItem>
                        })}
                    </ColFlex>
                    </div>
                </div>
            }
            else{
                elements = <div onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }
                }} tabIndex={0} id={id} ref={dragRef} style={{...style,position:'relative'}}>
                    <div ref={drag}>
                        <ColFlex style={{border:'1px solid',position:'relative',height:'100%',width:'100%'}}>
                        {id}
                    </ColFlex>
                    </div>
                </div>
            }
        }
        else if(type == '00'){
            let style = json['props']['style'];
            const position = json['addition']['position'];
            if(isLayoutChildren != undefined && isLayoutChildren){
                elements = <div tabIndex={0} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }
                }} onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} id={id} ref={drag} style={{width:style['width'],height:style['height'],position:'relative'}}>
                    <BaseChart option={json['props']['options']} width={style['width']} height={style['height']}/>
                </div>;
            }else{
                elements = <div tabIndex={0} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }
                }} onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} id={id} ref={drag} style={{...style,position:'absolute',top:position['top'],left:position['left']}}>
                    <BaseChart option={json['props']['options']} width={style['width']} height={style['height']}/>
                </div>;
            }
        }
        else if(type == '01'){
            let style = json['props']['style'];
            const position = json['addition']['position'];
            if(isLayoutChildren != undefined && isLayoutChildren){
                elements = <div tabIndex={0} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }
                }} onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} id={id} ref={drag} style={{width:style['width'],height:style['height'],position:'relative'}}>
                    <MapChart option={json['props']['options']} width={style['width']} height={style['height']}/>
                </div>;
            }else{
                elements = <div tabIndex={0} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }
                }} onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} id={id} ref={drag} style={{...style,position:'absolute',top:position['top'],left:position['left']}}>
                    <MapChart option={json['props']['options']} width={style['width']} height={style['height']}/>
                </div>;
            }
        }
        else if(type == 'custom'){
            const data = json['props']['divcomponentdata'];
            const dom = data == "" ? "<div>请在右侧录入自定义组件</div>" : data;
            const position = json['addition']['position'];
            /*if(json['children'] && json['children']['length'] > 0){
                elements = <div onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} id={id} ref={dragRef} style={{...style,top:position['top'],left:position['left']}}>
                    <div ref={drag}>
                        {json['children'].map((value)=>{
                            return <Element key={value['id']} json={value}/>
                        })}
                    </div>
                </div>;
            }else*/
            if(isLayoutChildren != undefined && isLayoutChildren){
                elements = <div onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} tabIndex={0} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }
                }}  id={id} ref={dragRef} style={{...style,position:'relative'}}>
                    <div dangerouslySetInnerHTML={{__html: dom}} id={id+'_inner'} ref={drag}>
                    </div>
                </div>;
            }else{
                elements = <div onClick={(event)=>{
                    event.stopPropagation();
                    setCurrentComponent(json);
                }} tabIndex={0} onKeyDown={(event)=>{
                    if(event.keyCode == 46){
                        event.stopPropagation();
                        const newJson = deleteComponent(json['id'],pageJson);
                        setPageJson(newJson);
                        setCurrentComponent(newJson);
                    }
                }} id={id} ref={dragRef} style={{...style,position:'absolute'}}>
                    <div dangerouslySetInnerHTML={{__html: dom}} id={id+'_inner'} ref={drag}>
                    </div>
                </div>;
            }
        }
    }

    return elements;
}